﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharpMUD.Framework.Workflow.Generic;

namespace SharpMUD.Framework.Net.Telnet
{
    public partial class TelnetSession
        : IControlledExecution, ISuspendableExecution
    {
        /// <summary>
        /// Causes the TelnetSession to begin processing and maintaining its connection
        /// </summary>
        public void Start()
        {
            if (this.ExecutionStatus == ExecutionStatusTokens.Suspended)
                this.Resume();
            if (this.ExecutionStatus != ExecutionStatusTokens.Initialized)
                throw new InvalidExecutionStatusTransitionException(this.ExecutionStatus, ExecutionStatusTokens.Starting);
            this.ExecutionStatus = (IExecutionStatusToken)ExecutionStatusTokens.Starting;

#if TELNET_SESSION_SELF_THREADED
            this._ThreadShouldBeAlive = true;
            this._Thread = new System.Threading.Thread(new System.Threading.ThreadStart(this.PulseLoop));
            this._Thread.Start();
#endif

            this.ExecutionStatus = ExecutionStatusTokens.Running;
        }

        /// <summary>
        /// Casues the TelnetSession to cease processing and maintenance of its connection
        /// </summary>
        public void Stop()
        {
            if (this.ExecutionStatus != ExecutionStatusTokens.Running &&
                this.ExecutionStatus != ExecutionStatusTokens.Suspended)
                throw new InvalidExecutionStatusTransitionException(this.ExecutionStatus, ExecutionStatusTokens.Stopping);
            this.ExecutionStatus = ExecutionStatusTokens.Stopping;

#if TELNET_SESSION_SELF_THREADED
            _ThreadShouldBeAlive = false;
            _Thread.Abort();
#endif

            this.ExecutionStatus = ExecutionStatusTokens.Stopped;
        }

        public void Suspend()
        {
            if (this.ExecutionStatus != ExecutionStatusTokens.Running)
                throw new InvalidExecutionStatusTransitionException(this.ExecutionStatus, ExecutionStatusTokens.Suspending);
            this.ExecutionStatus = ExecutionStatusTokens.Suspending;

#if TELNET_SESSION_SELF_THREADED
            _Thread.Suspend();
#endif

            this.ExecutionStatus = ExecutionStatusTokens.Suspended;
        }

        public void Resume()
        {
            if (this.ExecutionStatus != ExecutionStatusTokens.Suspended)
                throw new InvalidExecutionStatusTransitionException(this.ExecutionStatus, ExecutionStatusTokens.Resuming);
            this.ExecutionStatus = ExecutionStatusTokens.Resuming;

#if TELNET_SESSION_SELF_THREADED
            _Thread.Resume();
#endif

            this.ExecutionStatus = ExecutionStatusTokens.Running;
        }

        #region IHasExecutionStatus Members

        private IExecutionStatusToken _ExecutionStatus;
        public IExecutionStatusToken ExecutionStatus
        {
            get
            {
                return _ExecutionStatus;
            }
            private set
            {
                IExecutionStatusToken oldValue = _ExecutionStatus;
                if (oldValue != value)
                {
                    _ExecutionStatus = value;
                    if (ExecutionStatusChanged != null)
                        ExecutionStatusChanged(this, new ValueChangedEventArgs<IExecutionStatusToken>(oldValue, value));
                }
            }
        }

        public event EventHandler<ValueChangedEventArgs<IExecutionStatusToken>> ExecutionStatusChanged;

        #endregion
    }
}
